package cn.tiger.service;

import cn.tiger.exception.BusinessException;
import cn.tiger.common.CodeMsg;
import cn.tiger.pojo.domain.Membership;
import cn.tiger.pojo.domain.User;
import cn.tiger.repository.MembershipRepository;
import cn.tiger.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

/**
 * 会员服务类
 * 
 * 提供会员管理相关的业务逻辑处理，包括充值、会员状态查询和更新等功能
 * 支持事务管理、会员权限验证和会员到期管理
 * 
 * @author AI Backend Team
 * @version 1.0
 * @since 2025-09-26
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class MembershipService {
    
    private final MembershipRepository membershipRepository;
    private final UserRepository userRepository;
    
    // 会员类型常量
    public static final String MEMBERSHIP_FREE = "FREE";
    public static final String MEMBERSHIP_VIP = "VIP";
    
    // 免费用户限制
    public static final int FREE_MAX_CONVERSATIONS = 2;  // 最多2个对话
    public static final int FREE_MAX_MESSAGES_PER_CONVERSATION = 10;  // 每个对话最多10条消息
    
    /**
     * 充值会员
     * @param userId 用户ID
     * @param amount 充值金额
     * @param months 会员月数
     * @return 充值记录ID
     */
    @Transactional
    public Long rechargeMembership(Long userId, BigDecimal amount, Integer months) {
        // 验证用户存在
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new BusinessException(new CodeMsg(404, "用户不存在")));
        
        // 验证充值参数
        if (amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) {
            throw new BusinessException(new CodeMsg(400, "充值金额必须大于0"));
        }
        
        if (months == null || months <= 0) {
            throw new BusinessException(new CodeMsg(400, "充值月数必须大于0"));
        }
        
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime newExpireTime;
        
        // 计算新的到期时间
        LocalDateTime currentExpireTime = user.getMembershipExpireTime();
        if (currentExpireTime == null || currentExpireTime.isBefore(now)) {
            // 如果当前没有会员或已过期，从现在开始计算
            newExpireTime = now.plusMonths(months);
        } else {
            // 如果当前会员未过期，在原有基础上延期
            newExpireTime = currentExpireTime.plusMonths(months);
        }
        
        // 创建充值记录
        Membership membership = new Membership();
        membership.setUserId(userId);
        membership.setMembershipType(MEMBERSHIP_VIP);
        membership.setStartTime(now);
        membership.setExpireTime(newExpireTime);
        membership.setAmount(amount);
        membership.setChargeTime(now);
        membership.setStatus((byte) 1);
        membership.setCreateTime(now);
        membership.setUpdateTime(now);
        
        Membership savedMembership = membershipRepository.save(membership);
        
        // 更新用户会员信息
        user.setMembershipType(MEMBERSHIP_VIP);
        user.setMembershipExpireTime(newExpireTime);
        userRepository.save(user);
        
        log.info("用户{}充值会员成功，充值金额{}，会员到期时间{}", userId, amount, newExpireTime);
        
        return savedMembership.getId();
    }
    
    /**
     * 检查用户当前会员状态
     * @param userId 用户ID
     * @return 是否为有效会员
     */
    public boolean isVipMember(Long userId) {
        User user = userRepository.findById(userId).orElse(null);
        if (user == null) {
            return false;
        }
        
        // 检查会员类型和到期时间
        if (!MEMBERSHIP_VIP.equals(user.getMembershipType())) {
            return false;
        }
        
        LocalDateTime expireTime = user.getMembershipExpireTime();
        if (expireTime == null) {
            return false;
        }
        
        return expireTime.isAfter(LocalDateTime.now());
    }
    
    /**
     * 获取用户会员信息
     * @param userId 用户ID
     * @return 会员信息
     */
    public User getUserMembershipInfo(Long userId) {
        return userRepository.findById(userId)
                .orElseThrow(() -> new BusinessException(new CodeMsg(404, "用户不存在")));
    }
    
    /**
     * 获取用户充值记录
     * @param userId 用户ID
     * @return 充值记录列表
     */
    public List<Membership> getUserMembershipRecords(Long userId) {
        return membershipRepository.findByUserIdOrderByCreateTimeDesc(userId);
    }
    
    /**
     * 检查用户是否可以创建新对话
     * @param userId 用户ID
     * @param currentConversationCount 当前对话数量
     * @return 是否可以创建
     */
    public boolean canCreateConversation(Long userId, long currentConversationCount) {
        if (isVipMember(userId)) {
            return true;  // VIP用户无限制
        }
        
        // 免费用户限制
        return currentConversationCount < FREE_MAX_CONVERSATIONS;
    }
    
    /**
     * 检查用户是否可以发送消息
     * @param userId 用户ID
     * @param conversationMessageCount 当前对话消息数量
     * @return 是否可以发送
     */
    public boolean canSendMessage(Long userId, long conversationMessageCount) {
        boolean isVip = isVipMember(userId);
        log.info("检查用户{}发送消息权限 - 是否VIP: {}, 当前消息数: {}, 限制: {}", 
                userId, isVip, conversationMessageCount, FREE_MAX_MESSAGES_PER_CONVERSATION);
        
        if (isVip) {
            log.info("用户{}是VIP，无限制", userId);
            return true;  // VIP用户无限制
        }
        
        // 免费用户限制（只计算用户发送的消息，不包括AI回复）
        boolean canSend = conversationMessageCount < FREE_MAX_MESSAGES_PER_CONVERSATION;
        log.info("免费用户检查结果: {} < {} = {}", 
                conversationMessageCount, FREE_MAX_MESSAGES_PER_CONVERSATION, canSend);
        return canSend;
    }
    
    /**
     * 更新过期会员状态
     * 定期任务调用，将过期的VIP用户转为免费用户
     */
    @Transactional
    public void updateExpiredMemberships() {
        LocalDateTime now = LocalDateTime.now();
        
        // 查找过期的VIP用户
        List<User> expiredUsers = userRepository.findAll().stream()
                .filter(user -> MEMBERSHIP_VIP.equals(user.getMembershipType()))
                .filter(user -> user.getMembershipExpireTime() != null)
                .filter(user -> user.getMembershipExpireTime().isBefore(now))
                .toList();
        
        for (User user : expiredUsers) {
            user.setMembershipType(MEMBERSHIP_FREE);
            user.setMembershipExpireTime(null);
            userRepository.save(user);
            log.info("用户{}会员已过期，转为免费用户", user.getId());
        }
    }
}